package com.youyoulong.framework.auth.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.youyoulong.framework.auth.vo.FrameUser;
import com.youyoulong.framework.util.EncryptUtils;
import com.youyoulong.framework.util.SpringContextUtil;
import com.youyoulong.framework.util.ThreadVariableUtil;

@Controller
@RequestMapping(value = "/auth")

public class AuthController {

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@RequestMapping(value = "/login", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	public @ResponseBody Map login(@RequestBody FrameUser user, HttpSession session, HttpServletRequest request)
			throws Exception {

		Map result = new HashMap();
		/* 就是代表当前的用户。 */
		Subject currentUser = SecurityUtils.getSubject();
		// 获取基于用户名和密码的令牌
		// 这里的token大家叫他令牌，也就相当于一张表格，你要去验证，你就得填个表，里面写好用户名密码，交给公安局的同志给你验证。
		UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(),
				EncryptUtils.encryptMD5(user.getPassword()));
		/*
		 * UsernamePasswordToken token = new UsernamePasswordToken(
		 * user.getUserName(), user.getPassword());
		 */
		// 但是，“已记住”和“已认证”是有区别的：
		// 已记住的用户仅仅是非匿名用户，你可以通过subject.getPrincipals()获取用户信息。但是它并非是完全认证通过的用户，当你访问需要认证用户的功能时，你仍然需要重新提交认证信息。
		// 这一区别可以参考亚马逊网站，网站会默认记住登录的用户，再次访问网站时，对于非敏感的页面功能，页面上会显示记住的用户信息，但是当你访问网站账户信息时仍然需要再次进行登录认证。
		token.setRememberMe(true);
		try {
			// 回调doGetAuthenticationInfo，进行认证
			currentUser.login(token);
			
			// 验证是否通过
			if (currentUser.isAuthenticated()) {
				ThreadVariableUtil.create().setAttribute(ThreadVariableUtil._sessionUserInfoKey, user);
				result.put("status", "100");
				result.put("message", SpringContextUtil.getMessage("auth.html.login.success"));
				result.put("tooken", currentUser.getPrincipal().toString());
			} else {
				result.put("status", "-100");
				result.put("message", SpringContextUtil.getMessage("auth.html.login.fail"));
			}
			
		} catch (AuthenticationException e) {
			result.put("status", "-100");
			result.put("message", SpringContextUtil.getMessage("auth.html.login.fail"));
		}

		return result;
	}

	@RequestMapping(value = "/logout")
	public ModelAndView logout(FrameUser user, HttpSession session, HttpServletRequest request) throws Exception {
		ModelAndView modelView = new ModelAndView();
		/* 就是代表当前的用户。 */
		Subject currentUser = SecurityUtils.getSubject();
		currentUser.logout();
		modelView.setViewName("redirect:/static/view/auth/login/login.html");
		return modelView;
	}
}
